home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / GLUT / progs / demos / ideas / track.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  26KB  |  1,048 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1995. */
  3.  
  4. /*
  5.  * (c) Copyright 1993, Silicon Graphics, Inc.
  6.  * ALL RIGHTS RESERVED 
  7.  * Permission to use, copy, modify, and distribute this software for 
  8.  * any purpose and without fee is hereby granted, provided that the above
  9.  * copyright notice appear in all copies and that both the copyright notice
  10.  * and this permission notice appear in supporting documentation, and that 
  11.  * the name of Silicon Graphics, Inc. not be used in advertising
  12.  * or publicity pertaining to distribution of the software without specific,
  13.  * written prior permission. 
  14.  *
  15.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  16.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  17.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  18.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  19.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  20.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  21.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  22.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  23.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  24.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  25.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  26.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  27.  * 
  28.  * US Government Users Restricted Rights 
  29.  * Use, duplication, or disclosure by the Government is subject to
  30.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  31.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  32.  * clause at DFARS 252.227-7013 and/or in similar or successor
  33.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  34.  * Unpublished-- rights reserved under the copyright laws of the
  35.  * United States.  Contractor/manufacturer is Silicon Graphics,
  36.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  37.  *
  38.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  39.  */
  40. #include <math.h>
  41. #include <sys/time.h>
  42. #include <stdio.h>
  43. #include <stdlib.h>
  44. #include "objects.h"
  45. #include <GL/glut.h>
  46.  
  47. #define X 0
  48. #define Y 1
  49. #define Z 2
  50.  
  51. #ifndef TRUE
  52. #define TRUE 1
  53. #endif
  54. #ifndef FALSE
  55. #define FALSE 0
  56. #endif
  57.  
  58. #define DEG *M_PI/180.0
  59. #define RAD *180.0/M_PI
  60.  
  61. float move_speed;        /* Spline distance per second */
  62.  
  63. int multisample = 0;        /* Antialias polygons? */
  64. int doublebuffer = 1;        /* Doublebuffer? */
  65.  
  66.  
  67. #define SPEED_SLOW        0.2    /* Spline distances per second */
  68. #define SPEED_MEDIUM        0.4
  69. #define SPEED_FAST        0.7
  70. #define SPEED_SUPER_FAST    1.0
  71.  
  72. #define O_NOMS        7
  73. #define O_4MS        8
  74. #define O_8MS        9
  75. #define O_16MS        10
  76.  
  77. static int RGBA_SB_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH;
  78.  
  79. static int RGBA_SB_ST_attributes = GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STEREO;
  80.  
  81. static int RGBA_DB_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH;
  82.  
  83. static int RGBA_DB_ST_attributes = GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH | GLUT_STEREO;
  84.  
  85. float idmat[4][4] = {
  86.     {1.0, 0.0, 0.0, 0.0},
  87.     {0.0, 1.0, 0.0, 0.0},
  88.     {0.0, 0.0, 1.0, 0.0},
  89.     {0.0, 0.0, 0.0, 1.0},
  90. };
  91.  
  92. float light1_ambient[] = { 0.0,0.0,0.0,1.0 };
  93. float light1_lcolor[] = { 1.0,1.0,1.0,1.0 };
  94. float light1_position[] = { 0.0,1.0,0.0,0.0 };
  95.  
  96. float light2_ambient[] = { 0.0,0.0,0.0,1.0 };
  97. float light2_lcolor[] = { 0.3,0.3,0.5,1.0 };
  98. float light2_position[] = { -1.0,0.0,0.0,0.0 };
  99.  
  100. float light3_ambient[] = { 0.2,0.2,0.2,1.0 };
  101. float light3_lcolor[] = { 0.2,0.2,0.2,1.0 };
  102. float light3_position[] = { 0.0,-1.0,0.0,0.0 };
  103.  
  104. float lmodel_LVW[] = { 0.0 };
  105. float lmodel_ambient[] = { 0.3,0.3,0.3,1.0 };
  106. float lmodel_TWO[] = { GL_TRUE };
  107.  
  108. float mat_logo_ambient[] = {0.1, 0.1, 0.1, 1.0};
  109. float mat_logo_diffuse[] = {0.5, 0.4, 0.7, 1.0};
  110. float mat_logo_specular[] = {1.0, 1.0, 1.0, 1.0};
  111. float mat_logo_shininess[] = {30.0};
  112.  
  113. float mat_holder_base_ambient[] = {0.0, 0.0, 0.0, 1.0};
  114. float mat_holder_base_diffuse[] = {0.6, 0.6, 0.6, 1.0};
  115. float mat_holder_base_specular[] = {0.8, 0.8, 0.8, 1.0};
  116. float mat_holder_base_shininess[] = {30.0};
  117.  
  118. float mat_holder_rings_ambient[] = { 0.0,0.0,0.0,1.0 };
  119. float mat_holder_rings_diffuse[] = { 0.9,0.8,0.0,1.0 };
  120. float mat_holder_rings_specular[] = { 1.0,1.0,1.0,1.0 };
  121. float mat_holder_rings_shininess[] = { 30.0 };
  122.  
  123. float mat_hemisphere_ambient[] = {0.0, 0.0, 0.0,1.0 };
  124. float mat_hemisphere_diffuse[] = {1.0, 0.2, 0.2,1.0 };
  125. float mat_hemisphere_specular[] = {0.5, 0.5, 0.5,1.0 };
  126. float mat_hemisphere_shininess[] = {20.0};
  127.  
  128. GLubyte stipple[32*32];
  129.  
  130. typedef float vector[3];
  131. typedef float vector4[4];
  132. typedef vector parameter[4];
  133.  
  134. /*
  135.  * Function definitions
  136.  */
  137. void initialize(void);
  138. void resize_window(int w, int h);
  139. void build_table(void);
  140. parameter *calc_spline_params(vector *ctl_pts, int n);
  141. void calc_spline(vector v, parameter *params, float current_time);
  142. void normalize(vector v);
  143. float dot(vector v1, vector v2);
  144. void draw_table(void);
  145. void draw_logo_shadow(void);
  146. void draw_hemisphere(void);
  147. void draw_logo(void);
  148. void draw_under_table(void);
  149. void draw_i(void);
  150. void draw_d(void);
  151. void draw_e(void);
  152. void draw_a(void);
  153. void draw_s(void);
  154. void draw_n(void);
  155. void draw_m(void);
  156. void draw_o(void);
  157. void draw_t(void);
  158.  
  159. int post_idle = 0;
  160. void idle(void);
  161. void do_post_idle(void);
  162. void display(void);
  163. void mouse(int b, int s, int x, int y);
  164. void keyboard(unsigned char c, int x, int y);
  165. void vis(int);
  166.  
  167. void init_materials(void) {
  168.   int x, y;
  169.  
  170.   /* Stipple pattern */
  171.   for (y = 0; y < 32; y++)
  172.     for (x = 0; x < 4; x++) 
  173.       stipple[y * 4 + x] = (y % 2) ? 0xaa : 0x55;
  174.  
  175.     glNewList(MAT_LOGO, GL_COMPILE); 
  176.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_logo_ambient); 
  177.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_logo_diffuse);
  178.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_logo_specular);
  179.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_logo_shininess);
  180.     glEndList(); 
  181.  
  182.     glNewList( MAT_HOLDER_BASE, GL_COMPILE);
  183.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_base_ambient); 
  184.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_base_diffuse);
  185.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_base_specular);
  186.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_base_shininess);
  187.     glEndList();
  188.  
  189.     glNewList(MAT_HOLDER_RINGS, GL_COMPILE); 
  190.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_holder_rings_ambient); 
  191.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_holder_rings_diffuse);
  192.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_holder_rings_specular);
  193.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_holder_rings_shininess);
  194.     glEndList();
  195.  
  196.     glNewList(MAT_HEMISPHERE, GL_COMPILE); 
  197.     glMaterialfv(GL_FRONT, GL_AMBIENT, mat_hemisphere_ambient); 
  198.     glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_hemisphere_diffuse);
  199.     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_hemisphere_specular);
  200.     glMaterialfv(GL_FRONT, GL_SHININESS, mat_hemisphere_shininess);
  201.     glEndList();
  202.  
  203. }
  204.  
  205. void init_lights(void) {
  206.   static float ambient[] = { 0.1, 0.1, 0.1, 1.0 };
  207.   static float diffuse[] = { 0.5, 1.0, 1.0, 1.0 };
  208.   static float position[] = { 90.0, 90.0, 150.0, 0.0 };
  209.   
  210.   glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
  211.   glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  212.   glLightfv(GL_LIGHT0, GL_POSITION, position);
  213.  
  214.   glLightfv (GL_LIGHT1, GL_AMBIENT, light1_ambient);
  215.   glLightfv (GL_LIGHT1, GL_SPECULAR, light1_lcolor);
  216.   glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_lcolor);
  217.   glLightfv (GL_LIGHT1, GL_POSITION, light1_position);
  218.     
  219.   glLightfv (GL_LIGHT2, GL_AMBIENT, light2_ambient);
  220.   glLightfv (GL_LIGHT2, GL_SPECULAR, light2_lcolor);
  221.   glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_lcolor);
  222.   glLightfv (GL_LIGHT2, GL_POSITION, light2_position);
  223.  
  224.   glLightfv (GL_LIGHT3, GL_AMBIENT, light3_ambient);
  225.   glLightfv (GL_LIGHT3, GL_SPECULAR, light3_lcolor);
  226.   glLightfv (GL_LIGHT3, GL_DIFFUSE, light3_lcolor);
  227.   glLightfv (GL_LIGHT3, GL_POSITION, light3_position);
  228.   
  229.   glLightModelfv (GL_LIGHT_MODEL_LOCAL_VIEWER, lmodel_LVW);
  230.   glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
  231. }
  232.  
  233. short dev, val;
  234.  
  235. float current_time=0.0;
  236. float hold_time=0.0;        /* Used when auto-running */
  237.  
  238. float tmplight[] = {
  239.     GL_POSITION, 0.0, 0.0, 0.0, 0.0, 
  240. };
  241.  
  242. GLfloat tv[4][4] = {
  243.   {1.0, 0.0, 0.0, 0.0},
  244.   {0.0, 1.0, 0.0, -1.0},
  245.   {0.0, 0.0, 1.0, 0.0},
  246.   {0.0, 0.0, 0.0, 0.0},
  247. };
  248.  
  249. #define TABLERES 12
  250.  
  251. float pcr, pcg, pcb, pca;
  252.  
  253. vector table_points[TABLERES+1][TABLERES+1];
  254. int tablecolors[TABLERES+1][TABLERES+1];
  255.  
  256. vector paper_points[4] = {
  257.     {-0.8, 0.0, 0.4},
  258.     {-0.2, 0.0, -1.4},
  259.     {1.0, 0.0, -1.0},
  260.     {0.4, 0.0, 0.8},
  261. };
  262.  
  263. float dot(vector, vector);
  264.  
  265. #define TIME 15
  266. #define START_TIME 0.6
  267.  
  268. vector light_pos_ctl[] = {
  269.  
  270.     {0.0, 1.8, 0.0},
  271.     {0.0, 1.8, 0.0},
  272.     {0.0, 1.6, 0.0},
  273.  
  274.     {0.0, 1.6, 0.0},
  275.     {0.0, 1.6, 0.0},
  276.     {0.0, 1.6, 0.0},
  277.     {0.0, 1.4, 0.0},
  278.  
  279.     {0.0, 1.3, 0.0},
  280.     {-0.2, 1.5, 2.0},
  281.     {0.8, 1.5, -0.4},
  282.     {-0.8, 1.5, -0.4},
  283.  
  284.     {0.8, 2.0, 1.0},
  285.     {1.8, 5.0, -1.8},
  286.     {8.0, 10.0, -4.0},
  287.     {8.0, 10.0, -4.0},
  288.     {8.0, 10.0, -4.0},
  289. };
  290.  
  291. vector logo_pos_ctl[] = {
  292.  
  293.     {0.0, -0.5, 0.0},
  294.  
  295.     {0.0, -0.5, 0.0},
  296.     {0.0, -0.5, 0.0},
  297.  
  298.     {0.0, -0.5, 0.0},
  299.     {0.0, -0.5, 0.0},
  300.     {0.0, -0.5, 0.0},
  301.     {0.0, 0.0, 0.0},
  302.  
  303.     {0.0, 0.6, 0.0},
  304.     {0.0, 0.75, 0.0},
  305.     {0.0, 0.8, 0.0},
  306.     {0.0, 0.8, 0.0},
  307.  
  308.     {0.0, 0.5, 0.0},
  309.     {0.0, 0.5, 0.0},
  310.     {0.0, 0.5, 0.0},
  311.     {0.0, 0.5, 0.0},
  312.     {0.0, 0.5, 0.0},
  313. };
  314.  
  315.  
  316. vector logo_rot_ctl[] = {
  317.  
  318.     {0.0, 0.0, -18.4},
  319.  
  320.     {0.0, 0.0, -18.4},
  321.     {0.0, 0.0, -18.4},
  322.  
  323.     {0.0, 0.0, -18.4},
  324.     {0.0, 0.0, -18.4},
  325.     {0.0, 0.0, -18.4},
  326.     {0.0, 0.0, -18.4},
  327.     {0.0, 0.0, -18.4},
  328.  
  329. /*    {90.0, 0.0, -90.0},
  330.     {180.0, 180.0, 90.0}, */
  331.     {240.0, 360.0, 180.0},
  332.     {90.0, 180.0, 90.0},
  333.  
  334.     {11.9, 0.0, -18.4},
  335.     {11.9, 0.0, -18.4},
  336.     {11.9, 0.0, -18.4},
  337.     {11.9, 0.0, -18.4},
  338.     {11.9, 0.0, -18.4},
  339. };
  340.  
  341.  
  342. vector view_from_ctl[] = {
  343.  
  344.     {-1.0, 1.0, -4.0},
  345.  
  346.     {-1.0, -3.0, -4.0},    /* 0 */
  347.     {-3.0, 1.0, -3.0},    /* 1 */
  348.  
  349.     {-1.8, 2.0, 5.4},    /* 2 */
  350.     {-0.4, 2.0, 1.2},    /* 3 */
  351.     {-0.2, 1.5, 0.6},    /* 4 */
  352.     {-0.2, 1.2, 0.6},    /* 5 */
  353.  
  354.     {-0.8, 1.0, 2.4},    /* 6 */
  355.     {-1.0, 2.0, 3.0},    /* 7 */
  356.     {0.0, 4.0, 3.6},    /* 8 */
  357.     {-0.8, 4.0, 1.2},    /* 9 */
  358.  
  359.     {-0.2, 3.0, 0.6},    /* 10 */
  360.     {-0.1, 2.0, 0.3},    /* 11 */
  361.     {-0.1, 2.0, 0.3},    /* 12 */
  362.     {-0.1, 2.0, 0.3},    /* 13 */
  363.     {-0.1, 2.0, 0.3},    /* 13 */
  364.  
  365.  
  366. };
  367.  
  368. vector view_to_ctl[] = {
  369.  
  370.     {-1.0, 1.0, 0.0},
  371.  
  372.     {-1.0, -3.0, 0.0},
  373.     {-1.0, 1.0, 0.0},
  374.  
  375.     {0.1, 0.0, -0.3},
  376.     {0.1, 0.0, -0.3},
  377.     {0.1, 0.0, -0.3},
  378.     {0.0, 0.2, 0.0},
  379.  
  380.     {0.0, 0.6, 0.0},
  381.     {0.0, 0.8, 0.0},
  382.     {0.0, 0.8, 0.0},
  383.     {0.0, 0.8, 0.0},
  384.  
  385.     {0.0, 0.8, 0.0},
  386.     {0.0, 0.8, 0.0},
  387.     {0.0, 0.8, 0.0},
  388.     {0.0, 0.8, 0.0},
  389.     {0.0, 0.8, 0.0},
  390.  
  391. };
  392.  
  393.  
  394. vector view_from, view_to, logo_pos, logo_rot;
  395. vector4 light_pos;
  396.  
  397. parameter *view_from_spline, *view_to_spline,
  398.       *light_pos_spline, *logo_pos_spline,
  399.       *logo_rot_spline;
  400.  
  401. parameter *calc_spline_params(vector *, int);
  402.  
  403. double a3, a4;
  404.  
  405. void ideas_usage(void)
  406. {
  407.   fprintf(stderr, "Usage: ideas [-a] [-m] [-d] -s{1-4}\n");
  408.   fprintf(stderr, "Press ESC to quit, 1-4 to control speed, any other key\n");
  409.   fprintf(stderr, "to pause.\n");
  410. }
  411.  
  412.   int auto_run;        /* If set, then automatically run forever */
  413.   float new_speed;    /* Set new animation speed? */
  414.   int timejerk;        /* Set to indicate time jerked! (menu pulled down) */
  415.   int paused = 0;    /* Paused? */
  416.   int right = 0;    /* Draw right eye? */
  417.   int resetclock;    /* Reset the clock? */
  418.   float timeoffset;    /* Used to compute timing */
  419.   struct timeval start;
  420.  
  421. int main(int argc, char **argv)
  422. {
  423.   int i;
  424.  
  425.   glutInit(&argc, argv);
  426.  
  427.   auto_run = 0;    /* Don't automatically run forever */
  428.   /* .4 spline distance per second by default */
  429.   move_speed = SPEED_MEDIUM;
  430.   new_speed = SPEED_MEDIUM;
  431.   timeoffset = START_TIME;
  432.   
  433.   for (i = 1; i < argc; i++) {
  434.     if (argv[i][0] != '-') {
  435.       break;
  436.     }
  437.     
  438.     switch(argv[i][1]) {
  439.     case 'a':    /* Keep running forever */
  440.       auto_run = 1;
  441.       break;
  442.     case 'm':    /* Multisample */
  443.       multisample = 1;
  444.       break;
  445.     case 'd':    /* Single buffer */
  446.       doublebuffer = 0;
  447.       break;
  448.     case 's':
  449.       switch(argv[i][2]) {
  450.       case '1':
  451.     move_speed = new_speed = SPEED_SLOW;
  452.     break;
  453.       case '2':
  454.     move_speed = new_speed = SPEED_MEDIUM;
  455.     break;
  456.       case '3':
  457.     move_speed = new_speed = SPEED_FAST;
  458.     break;
  459.       case '4':
  460.     move_speed = new_speed = SPEED_SUPER_FAST;
  461.     break;
  462.       }
  463.       break;
  464.     default:
  465.       ideas_usage();
  466.       break;
  467.     }
  468.   }
  469.   
  470.   initialize();
  471.   
  472.   current_time = timeoffset;
  473.   resetclock = 1;
  474.   timejerk = 0;
  475.   glutMainLoop();
  476.   return 0;             /* ANSI C requires main to return int. */
  477. }
  478.  
  479. void idle(void) 
  480. {
  481.     if ((current_time) > (TIME*1.0)-3.0) {
  482.       if (auto_run) {
  483.     hold_time += current_time - (TIME - 3.001);
  484.     if (hold_time > 3.0) {    /* 3 second hold */
  485.       hold_time = 0.0;
  486.       resetclock = 1;
  487.     }
  488.       } else {
  489.         if(!resetclock) glutIdleFunc(NULL);
  490.       }
  491.       current_time = (TIME*1.0)-3.001;
  492.     } else {
  493.        post_idle = 1;
  494.     }
  495.     glutPostRedisplay();
  496. }
  497.  
  498. void
  499. mouse(int b, int s, int x, int y)
  500. {
  501.    if(b == GLUT_LEFT_BUTTON && s == GLUT_DOWN) {
  502.       resetclock = 1;
  503.       paused = 0;
  504.       glutIdleFunc(idle);
  505.    }
  506. }
  507.  
  508. void
  509. keyboard(unsigned char c, int x, int y)
  510. {
  511.    switch(c) {
  512.    case 27:
  513.       exit(0);
  514.       break;
  515.    case '1':
  516.       new_speed = SPEED_SLOW;
  517.       break;
  518.    case '2':
  519.       new_speed = SPEED_MEDIUM;
  520.       break;
  521.    case '3':
  522.       new_speed = SPEED_FAST;
  523.       break;
  524.    case '4':
  525.       new_speed = SPEED_SUPER_FAST;
  526.       break;
  527.    default:
  528.       if (paused) timejerk = 1;
  529.       paused = ~paused;
  530.       if(paused) {
  531.      glutIdleFunc(NULL);
  532.       } else {
  533.      glutIdleFunc(idle);
  534.       }
  535.    }
  536. }
  537.  
  538. void
  539. vis(int visible)
  540. {
  541.   if (visible == GLUT_VISIBLE) {
  542.       if(!paused) glutIdleFunc(idle);
  543.       do_post_idle();
  544.   } else {
  545.       if(!paused) glutIdleFunc(NULL);
  546.   }
  547. }
  548.  
  549. void display(void)
  550. {
  551.   float x, y, z, c;
  552.  
  553.     calc_spline(view_from, view_from_spline, current_time);
  554.     calc_spline(view_to, view_to_spline, current_time);
  555.     calc_spline(light_pos, light_pos_spline, current_time);
  556.     light_pos[3] = 0.0;
  557.     calc_spline(logo_pos, logo_pos_spline, current_time);
  558.     calc_spline(logo_rot, logo_rot_spline, current_time);
  559.     
  560.     tmplight[1] = light_pos[X] - logo_pos[X];
  561.     tmplight[2] = light_pos[Y] - logo_pos[Y];
  562.     tmplight[3] = light_pos[Z] - logo_pos[Z];
  563.     
  564.     glNewList(LIGHT_TMP, GL_COMPILE); 
  565.     glMaterialf(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, * tmplight); 
  566.     glEndList();
  567.     
  568.     tv[0][0] = tv[1][1] = tv[2][2] = light_pos[Y];
  569.     
  570.     glColor3ub(0,  0,  0);
  571.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
  572.     
  573.     /*
  574.      * SHADOW
  575.      */
  576.     glMatrixMode(GL_MODELVIEW);
  577.     glLoadIdentity();
  578.     gluLookAt(view_from[X], view_from[Y], view_from[Z], 
  579.           view_to[X], view_to[Y], view_to[Z],
  580.           0.0, 1.0, 0.0);
  581.     
  582.     if (view_from[Y] > 0.0) draw_table();
  583.  
  584.     glEnable(GL_CULL_FACE); 
  585.     glDisable(GL_DEPTH_TEST); 
  586.  
  587.     if (logo_pos[Y] < 0.0) {
  588.       
  589.       if (logo_pos[Y]>-0.33) {
  590.     /* We're emerging from the table */
  591.     c = 1.0 - (logo_pos[Y]) / -0.33;
  592.     pca /= 4.0;
  593.     glColor3ub((int)(128.0*(1.0-c)*0.5 + 255.0*pca*c),
  594.            (int)(102.0*(1.0-c)*0.5 + 255.0*pca*c),
  595.            (int)(179.0*(1.0-c)*0.5 + 200.0*pca*c));
  596.       } else {
  597.     /* Still under table */
  598.     glColor3ub(128/2,  102/2,  179/2);
  599.       }
  600.       
  601.       glPushMatrix();
  602.       glScalef(0.04,  0.0,  0.04);
  603.       glRotatef(0.1 * (-900), 1.0, 0.0, 0.0);
  604.       glRotatef(0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  605.       glRotatef(0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  606.       glRotatef(0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  607.       glRotatef(0.1 * (353), 1.0, 0.0, 0.0);
  608.       glRotatef(0.1 * (450), 0.0, 1.0, 0.0);
  609.       draw_logo_shadow();
  610.       glPopMatrix();
  611.     }
  612.     
  613.     if (logo_pos[Y] > 0.0) {
  614.       glPushMatrix();
  615.       if (logo_pos[Y]<0.33) {
  616.     pca /= 4.0;
  617.     c = 1.0 - (logo_pos[Y])/0.33;
  618.     glColor3ub((int)(255.0*pca*c),
  619.            (int)(255.0*pca*c),
  620.            (int)(200.0*pca*c));
  621.       } else {
  622.     glColor3ub(0, 0, 0);
  623.       }
  624.       
  625.       glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  626.       glMultMatrixf(&tv[0][0]);
  627.       glTranslatef(-light_pos[X]+logo_pos[X],
  628.            -light_pos[Y]+logo_pos[Y],
  629.            -light_pos[Z]+logo_pos[Z]);
  630.       glScalef(0.04,  0.04,  0.04);
  631.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  632.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  633.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  634.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  635.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  636.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  637.  
  638.  
  639.       glEnable(GL_POLYGON_STIPPLE);
  640.       glPolygonStipple(stipple);
  641.       draw_logo_shadow();
  642.       glDisable(GL_POLYGON_STIPPLE);
  643.       glPopMatrix();
  644.     }
  645.     /*
  646.      * DONE SHADOW 
  647.      */
  648.  
  649.  
  650.     glEnable(GL_DEPTH_TEST);
  651.     glDisable(GL_CULL_FACE);
  652.     glEnable(GL_LIGHTING);
  653.  
  654.     glMatrixMode(GL_PROJECTION);
  655.     glLoadIdentity();
  656.     gluPerspective(.1*(450),  5.0/4.0,  0.5,  20.0);
  657.     glMatrixMode(GL_MODELVIEW);
  658.     glLoadMatrixf(&idmat[0][0]); 
  659.     
  660.     gluLookAt(view_from[X],  view_from[Y],  view_from[Z],
  661.           view_to[X],  view_to[Y],  view_to[Z], 
  662.           0.0, 1.0, 0.0);
  663.     
  664.     glCallList( MAT_HOLDER_RINGS); 
  665.     
  666.     glPushMatrix();
  667.     glTranslatef(light_pos[X],  light_pos[Y],  light_pos[Z]);
  668.     glScalef(0.1,  0.1,  0.1);
  669.     
  670.     x = light_pos[X] - logo_pos[X];
  671.     y = light_pos[Y] - logo_pos[Y];
  672.     z = light_pos[Z] - logo_pos[Z];
  673.     
  674.     if (x!=0.0) {
  675.       a3 = -atan2(z, x)*10.0 RAD;
  676.     } else a3 = 0.0;
  677.     
  678.     a4 = -atan2(sqrt(x*x + z*z), y)*10.0 RAD;
  679.     
  680.     glRotatef (0.1 * ((int)a3), 0.0, 1.0, 0.0);
  681.     glRotatef (0.1 * ((int)a4), 0.0, 0.0, 1.0);
  682.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  683.     
  684.     glEnable(GL_LIGHT2);
  685.     glEnable(GL_LIGHT3);
  686.     glCallList(MAT_HEMISPHERE);
  687.     glEnable(GL_NORMALIZE);
  688.     draw_hemisphere();
  689.     glDisable(GL_NORMALIZE);
  690.     glPopMatrix();
  691.  
  692.     glDisable(GL_LIGHT2);
  693.     glDisable(GL_LIGHT3); 
  694.     glEnable(GL_LIGHT1);
  695.     glLightfv(GL_LIGHT1, GL_POSITION, light_pos);
  696.     
  697.     if (logo_pos[Y] > -0.33) {
  698.  
  699.       glCallList(MAT_LOGO);
  700.     
  701.       glPushMatrix();
  702.       glTranslatef(logo_pos[X],  logo_pos[Y],  logo_pos[Z]);
  703.       glScalef(0.04,  0.04,  0.04);
  704.       glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  705.       glRotatef (0.1 * ((int)(10.0*logo_rot[Z])), 0.0, 0.0, 1.0);
  706.       glRotatef (0.1 * ((int)(10.0*logo_rot[Y])), 0.0, 1.0, 0.0);
  707.       glRotatef (0.1 * ((int)(10.0*logo_rot[X])), 1.0, 0.0, 0.0);
  708.       glRotatef (0.1 * (353), 1.0, 0.0, 0.0);
  709.       glRotatef (0.1 * (450), 0.0, 1.0, 0.0);
  710.       glEnable(GL_LIGHTING);
  711.       draw_logo();
  712.       glPopMatrix();
  713.     }
  714.     
  715.     if (view_from[Y] < 0.0) draw_under_table();
  716.     
  717.     glutSwapBuffers();
  718.  
  719.     if(post_idle) do_post_idle();
  720. }
  721.  
  722. void do_post_idle(void)
  723. {
  724.   struct timeval current;
  725.   float timediff;    
  726.  
  727.     /* Time jerked -- adjust clock appropriately */
  728.     if (timejerk) {
  729.       timejerk = 0;
  730.       timeoffset = current_time;
  731.       gettimeofday(&start, NULL);
  732.     }
  733.     
  734.     /* Reset our timer */
  735.     if (resetclock) {
  736.       resetclock = 0;
  737.       paused = 0;
  738.       timeoffset = START_TIME;
  739.       gettimeofday(&start, NULL);
  740.     }
  741.     
  742.     /* Compute new time */
  743.     gettimeofday(¤t, NULL);
  744.     timediff = (current.tv_sec - start.tv_sec) + 
  745.       (current.tv_usec - start.tv_usec) / 1000000.0;
  746.     if (!paused) {
  747.        current_time = timediff * move_speed + timeoffset;
  748.     }
  749.     
  750.     /* Adjust to new speed */
  751.     if (new_speed != move_speed) {
  752.       move_speed = new_speed;
  753.       timeoffset = current_time;
  754.       gettimeofday(&start, NULL);
  755.     }
  756.     post_idle = 0;
  757. }
  758.  
  759. void resize_window(int w, int h) 
  760. {
  761.   glMatrixMode(GL_PROJECTION);
  762.   glLoadIdentity();
  763.   gluPerspective (45.0, 5.0/4.0, 0.5, 20.0); 
  764.   glMatrixMode(GL_MODELVIEW);
  765.   glLoadIdentity();
  766.   glViewport(0, 0, w, h);
  767. }
  768.  
  769. void initialize(void)
  770. {
  771.     int attr;
  772.  
  773.     attr = doublebuffer ? RGBA_DB_attributes : RGBA_SB_attributes;
  774.     glutInitDisplayMode(attr);
  775.     glutInitWindowSize(300, 240);
  776.     glutCreateWindow("Ideas");
  777.  
  778.     if (multisample) glEnable(GL_POLYGON_SMOOTH); 
  779.     
  780.     init_lights();
  781.     init_materials();
  782.  
  783.     build_table();
  784.  
  785.     view_from_spline = calc_spline_params(view_from_ctl, TIME);
  786.     view_to_spline = calc_spline_params(view_to_ctl, TIME);
  787.     light_pos_spline = calc_spline_params(light_pos_ctl, TIME);
  788.     logo_pos_spline = calc_spline_params(logo_pos_ctl, TIME);
  789.     logo_rot_spline = calc_spline_params(logo_rot_ctl, TIME);
  790.  
  791.     glutReshapeFunc(resize_window);
  792.     glutDisplayFunc(display);
  793.     glutMouseFunc(mouse);
  794.     glutKeyboardFunc(keyboard);
  795.     glutVisibilityFunc(vis);
  796.  
  797.     glMatrixMode(GL_MODELVIEW);
  798. }
  799.  
  800.  
  801. void build_table(void) 
  802. {
  803.     float i, j;
  804.  
  805.     for (j=0.0; j<=TABLERES*1.0; j+=1.0) {
  806.     for (i=0.0; i<=TABLERES*1.0; i+=1.0) {
  807.         table_points[(int)j][(int)i][Z] = (i-TABLERES*1.0/2.0)/2.0;
  808.         table_points[(int)j][(int)i][X] = (j-TABLERES*1.0/2.0)/2.0;
  809.         table_points[(int)j][(int)i][Y] = 0.0;
  810.     }
  811.     }
  812. }
  813.  
  814.  
  815. void draw_table(void)
  816. {
  817.     float c;
  818.     int i, j;
  819.     int k, l;
  820.     float ov[3], lv[3];
  821.  
  822.     glDisable(GL_DEPTH_TEST);
  823.     glDisable(GL_LIGHTING);
  824.  
  825.     ov[X] = light_pos[X]-logo_pos[X];
  826.     ov[Y] = light_pos[Y]-logo_pos[Y];
  827.     ov[Z] = light_pos[Z]-logo_pos[Z];
  828.  
  829.     normalize(ov);
  830.  
  831.     for (j=0; j<=TABLERES; j++) {
  832.       for (i=0; i<=TABLERES; i++) {
  833.     lv[X] = light_pos[X] - table_points[j][i][X];
  834.     lv[Y] = light_pos[Y] - table_points[j][i][Y];
  835.     lv[Z] = light_pos[Z] - table_points[j][i][Z];
  836.     normalize(lv);
  837.     if ((c = dot(lv, ov))<0.0) c = 0.0;
  838.     c = c * c * c * lv[Y] * 255.0;
  839.     /* fade */
  840.     if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  841.       c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  842.     
  843.     tablecolors[j][i] = (int)c;
  844.       }
  845.     }
  846.     
  847.     
  848.     for (l=0; l<TABLERES; l++) {
  849.       
  850.       glBegin(GL_TRIANGLE_STRIP);
  851.       for (k=0; k<=TABLERES; k++) {
  852.     glColor3ub(tablecolors[l][k],
  853.            tablecolors[l][k],
  854.            tablecolors[l][k]);
  855.     glVertex3fv(table_points[l][k]);
  856.  
  857.     glColor3ub(tablecolors[l+1][k],
  858.            tablecolors[l+1][k], 
  859.            tablecolors[l+1][k]);
  860.     glVertex3fv(table_points[l+1][k]);
  861.     
  862.       }
  863.     glEnd();
  864.     }
  865.  
  866.     if (logo_pos[Y]>-0.33 && logo_pos[Y]<0.33) {
  867.     glEnable(GL_DEPTH_TEST);
  868.     }
  869.  
  870.     pca = 0.0;
  871.     glBegin(GL_POLYGON);
  872.     for (i=0; i<4; i++) {
  873.       lv[X] = light_pos[X] - paper_points[i][X];
  874.       lv[Y] = light_pos[Y] - paper_points[i][Y];
  875.       lv[Z] = light_pos[Z] - paper_points[i][Z];
  876.       normalize(lv);
  877.       if ((c = dot(lv, ov))<0.0) c = 0.0;
  878.       c = c * c * c * lv[Y];
  879.       /* fade */
  880.       if ((current_time>TIME-5.0) && (current_time<TIME-3.0)) 
  881.     c *= 1.0 - (current_time-(TIME-5.0)) * 0.5;
  882.       
  883.       pcr = c * 255; pcg = c * 255; pcb = c * 200;
  884.       pca += c;
  885.       glColor3ub((int)pcr,  (int)pcg,  (int)pcb);
  886.       glVertex3fv(paper_points[i]);
  887.     }
  888.     glEnd();
  889.  
  890.     glPushMatrix();
  891.     glRotatef (0.1 * (-184), 0.0, 1.0, 0.0);
  892.     glTranslatef(-0.3, 0.0, -0.8);
  893.     glRotatef (0.1 * (-900), 1.0, 0.0, 0.0);
  894.     glScalef(0.015, 0.015, 0.015);
  895.  
  896.  
  897.     if (current_time>TIME*1.0-5.0) {
  898.     c = (current_time-(TIME*1.0-5.0))/2.0;
  899.     glColor3ub((int)(c*255.0),  (int)(c*255.0),  (int)(c*255.0));
  900.     } else glColor3ub(0,  0,  0);
  901.  
  902.     glDisable(GL_DEPTH_TEST);
  903.  
  904.     draw_i();
  905.     glTranslatef(3.0,  0.0,  0.0);
  906.  
  907.     draw_d();
  908.     glTranslatef(6.0,  0.0,  0.0);
  909.  
  910.     draw_e();
  911.     glTranslatef(5.0,  0.0,  0.0);
  912.  
  913.     draw_a();
  914.     glTranslatef(6.0,  0.0,  0.0);
  915.  
  916.     draw_s();
  917.     glTranslatef(10.0,  0.0,  0.0);
  918.  
  919.     draw_i();
  920.     glTranslatef(3.0,  0.0,  0.0);
  921.  
  922.     draw_n();
  923.     glTranslatef(-31.0,  -13.0,  0.0);
  924.  
  925.     draw_m();
  926.     glTranslatef(10.0,  0.0,  0.0);
  927.  
  928.     draw_o();
  929.     glTranslatef(5.0,  0.0,  0.0);
  930.  
  931.     draw_t();
  932.     glTranslatef(4.0,  0.0,  0.0);
  933.  
  934.     draw_i();
  935.     glTranslatef(3.5,  0.0,  0.0);
  936.  
  937.     draw_o();
  938.     glTranslatef(5.0,  0.0,  0.0);
  939.  
  940.     draw_n();
  941.  
  942.     glPopMatrix();
  943.  
  944. }
  945.  
  946.  
  947.  
  948. void draw_under_table(void) 
  949. {
  950.     int k, l;
  951.  
  952.     if(FALSE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  953.  
  954.  
  955.     glColor3ub(0,  0,  0);
  956.  
  957.     for (l=0; l<TABLERES; l++) {
  958.  
  959.     glBegin(GL_TRIANGLE_STRIP);
  960.     for (k=0; k<=TABLERES; k++) {
  961.  
  962.         glVertex3fv(table_points[l][k]);
  963.         glVertex3fv(table_points[l+1][k]);
  964.  
  965.     }
  966.     glEnd();
  967.     }
  968.  
  969.     if(TRUE) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);
  970.  
  971. }
  972.  
  973.  
  974.  
  975. void calc_spline(vector v, parameter *params, float current_time)
  976. {
  977.  
  978.     float t;
  979.     int i;
  980.  
  981.     t = current_time - (float)((int)current_time);
  982.  
  983.     for (i=0; i<3; i++) {
  984.  
  985.  
  986.     v[i] = params[(int)current_time][3][i] +
  987.            params[(int)current_time][2][i] * t +
  988.            params[(int)current_time][1][i] * t * t +
  989.            params[(int)current_time][0][i] * t * t * t;
  990.     }
  991.  
  992. }
  993.  
  994.  
  995. parameter *calc_spline_params(vector *ctl_pts, int n)
  996. {
  997.  
  998.     int i, j;
  999.     parameter *params;
  1000.  
  1001.     if (n<4) {
  1002.     fprintf(stderr,
  1003.         "calc_spline_params: not enough control points\n");
  1004.     return (NULL);
  1005.     }
  1006.  
  1007.     params = (parameter *)malloc(sizeof(parameter) * (n-3));
  1008.  
  1009.     for (i=0; i<n-3; i++) {
  1010.  
  1011.     for (j=0; j<3; j++) {
  1012.  
  1013.         params[i][3][j] = ctl_pts[i+1][j];
  1014.         params[i][2][j] = ctl_pts[i+2][j] - ctl_pts[i][j];
  1015.         params[i][1][j] =  2.0 * ctl_pts[i][j] +
  1016.                   -2.0 * ctl_pts[i+1][j] +
  1017.                    1.0 * ctl_pts[i+2][j] +
  1018.                   -1.0 * ctl_pts[i+3][j];
  1019.         params[i][0][j] = -1.0 * ctl_pts[i][j] +
  1020.                    1.0 * ctl_pts[i+1][j] +
  1021.                   -1.0 * ctl_pts[i+2][j] +
  1022.                    1.0 * ctl_pts[i+3][j];
  1023.  
  1024.     }
  1025.     }
  1026.  
  1027.     return (params);
  1028. }
  1029.  
  1030.  
  1031. void normalize(vector v)
  1032. {
  1033.     float r;
  1034.  
  1035.     r = sqrt(v[X]*v[X] + v[Y]*v[Y] + v[Z]*v[Z]);
  1036.  
  1037.     v[X] /= r;
  1038.     v[Y] /= r;
  1039.     v[Z] /= r;
  1040. }
  1041.  
  1042.  
  1043. float dot(vector v1, vector v2)
  1044. {
  1045.     return v1[X]*v2[X]+v1[Y]*v2[Y]+v1[Z]*v2[Z];
  1046. }
  1047.  
  1048.